#include <simulator/targetMachine/registerMap.h>

namespace simulator {
    bool RegisterMap::add_reg16(const std::shared_ptr<Register<u16>> &reg) {
        if (m_reg16_map.find(reg->name()) != m_reg16_map.end()) {
            return false;
        }
        m_reg16_map[reg->name()] = reg;
        return true;
    }

    bool RegisterMap::add_reg32(const std::shared_ptr<Register<u32>> &reg) {
        if (m_reg32_map.find(reg->name()) != m_reg32_map.end()) {
            return false;
        }
        m_reg32_map[reg->name()] = reg;
        return true;
    }

    bool RegisterMap::add_reg64(const std::shared_ptr<Register<u64>> &reg) {
        if (m_reg64_map.find(reg->name()) != m_reg64_map.end()) {
            return false;
        }
        m_reg64_map[reg->name()] = reg;
        return true;
    }

    std::shared_ptr<Register<u16>> RegisterMap::get_reg16(const std::string &reg_name) const {
        auto target_reg = m_reg16_map.find(reg_name);
        if (target_reg != m_reg16_map.end()) {
            return target_reg->second;
        }
        return nullptr;
    }

    std::shared_ptr<Register<u32>> RegisterMap::get_reg32(const std::string &reg_name) const {
        auto target_reg = m_reg32_map.find(reg_name);
        if (target_reg != m_reg32_map.end()) {
            return target_reg->second;
        }
        return nullptr;
    }

    std::shared_ptr<Register<u64>> RegisterMap::get_reg64(const std::string &reg_name) const {
        auto target_reg = m_reg64_map.find(reg_name);
        if (target_reg != m_reg64_map.end()) {
            return target_reg->second;
        }
        return nullptr;
    }

    RegisterMap::RegisterMap(const RegisterMap &register_map) {
        for (const auto &register16: register_map.m_reg16_map) {
            auto new_reg_16 = std::make_shared<Register<u16>>(*register16.second);
            m_reg16_map[register16.first] = new_reg_16;
        }

        for (const auto &register32: register_map.m_reg32_map) {
            auto new_reg_32 = std::make_shared<Register<u32>>(*register32.second);
            m_reg32_map[register32.first] = new_reg_32;
        }

        for (const auto &register64: register_map.m_reg64_map) {
            auto new_reg_64 = std::make_shared<Register<u64>>(*register64.second);
            m_reg64_map[register64.first] = new_reg_64;
        }
    }
}